iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
0
Mobile Development

小孩子才做選擇 ! Flutter & React Native 我全都要系列 第 13

[Day13] 與 Firebase 結合之自動上傳 DB 記帳

  • 分享至 

  • xImage
  •  

[Day13] 與 Firebase 結合之自動上傳 DB 記帳

我很懶,所以對發票時當然要順便記帳啊XD

首先,介紹我們今天使用的套件

首先,介紹我們今天使用的套件

firebase 的 react-native 套件
https://github.com/gre/react-native-view-shot

建立一個Firebase新項目

訪問Firebase控制台。
https://ithelp.ithome.com.tw/upload/images/20190929/201042202lRMFw1mh7.png

https://ithelp.ithome.com.tw/upload/images/20190929/20104220VAlUvbcS2F.png

https://ithelp.ithome.com.tw/upload/images/20190929/20104220c53ZhHHyHN.png

https://ithelp.ithome.com.tw/upload/images/20190929/20104220uNxmfZXiPE.png

https://ithelp.ithome.com.tw/upload/images/20190929/20104220ZTpEHqcUcs.png

https://ithelp.ithome.com.tw/upload/images/20190929/20104220kJqLrdQF38.png

單擊Add project如下所示的框:

firebase 的 react-native 套件的安裝方法

npm install --save react-native-firebase


=============Podfile================
  pod 'Firebase/Core'

  pod 'Firebase/Auth'
  pod 'Firebase/Database'
  pod 'Firebase/Functions'
  pod 'Firebase/DynamicLinks'
  pod 'Firebase/Firestore'
  pod 'Firebase/Messaging'
  pod 'Firebase/RemoteConfig'
  pod 'Firebase/Storage'
  pod 'Firebase/Performance'
  pod 'Fabric'
  pod 'Crashlytics'
  # add the Firebase pod for Google Analytics
pod 'Firebase/Analytics'
# add pods for any other desired Firebase products
# https://firebase.google.com/docs/ios/setup#available-pods
  =============================

cd ios && pod install && cd .. 
        ///安裝 pod 0.60以後不需要 使用 link or rnpm



https://rnfirebase.io/docs/v5.x.x/firestore/transactions

https://rnfirebase.io/docs/v5.x.x/installation/initial-setup

來看看精美的效果圖

要跟圖ㄧ樣才有成功喔!!

https://ithelp.ithome.com.tw/upload/images/20190929/20104220DIHTBBPXCa.png

廢話不多說,上扣

import React from 'react';
import { StyleSheet, Platform, Image, Text, View, ScrollView } from 'react-native';

import firebase from 'react-native-firebase';
import { GoogleSignin, GoogleSigninButton } from 'react-native-google-signin';

///參照 GoogleService-Info.plist 中的欄位
const iosConfig = {
  clientId: 'CLIENT_ID',
  appId: 'GOOGLE_APP_ID',
  apiKey: 'API_KEY',
  databaseURL: 'DATABASE_URL',
  storageBucket: 'STORAGE_BUCKET',
  messagingSenderId: 'GCM_SENDER_ID',
  projectId: 'PROJECT_ID',

  // enable persistence by adding the below flag
  persistence: true,
};

 firebase.initializeApp(
  iosConfig
).onReady().then((app) => {
  const ref = firebase.firestore().collection('cities').doc('London');
  app
    .firestore()
    .runTransaction(async transaction => {
      const doc = await transaction.get(ref);
      // if it does not exist set the population to one
      if (!doc.exists) {
        transaction.set(ref, { population: 1 });
        // return the new value so we know what the new population is
        return 1;
      }
      // exists already so lets increment it + 1
      const newPopulation = doc.data().population + 1;
      transaction.update(ref, {
        population: newPopulation,
      });
      // return the new value so we know what the new population is
      return newPopulation;
    })
    .then(newPopulation => {
      console.warn(
        `Transaction successfully committed and new population is '${newPopulation}'.`
      );
    })
    .catch(error => {
      console.warn('Transaction failed: ', error);
    });
});

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      isSigninInProgress: "",

    };
  }


  componentDidMount() {


  }


  render() {
    return (
      <ScrollView>
        <View style={styles.container}>
          {/* <Image source={require('./assets/ReactNativeFirebase.png')} style={[styles.logo]} /> */}
          <Text style={styles.welcome}>
            Welcome to {'\n'} React Native Firebase
          </Text>
          <Text style={styles.instructions}>
            To get started, edit App.js
          </Text>
          {Platform.OS === 'ios' ? (
            <Text style={styles.instructions}>
              Press Cmd+R to reload,{'\n'}
              Cmd+D or shake for dev menu
            </Text>
          ) : (
              <Text style={styles.instructions}>
                Double tap R on your keyboard to reload,{'\n'}
                Cmd+M or shake for dev menu
            </Text>
            )}
          <View style={styles.modules}>
            <Text style={styles.modulesHeader}>The following Firebase modules are pre-installed:</Text>
            {firebase.admob.nativeModuleExists && <Text style={styles.module}>admob()</Text>}
            {firebase.analytics.nativeModuleExists && <Text style={styles.module}>analytics()</Text>}
            {firebase.auth.nativeModuleExists && <Text style={styles.module}>auth()</Text>}
            {/* https://rnfirebase.io/docs/v5.x.x/auth/social-auth */}
            {firebase.config.nativeModuleExists && <Text style={styles.module}>config()</Text>}
            {firebase.crashlytics.nativeModuleExists && <Text style={styles.module}>crashlytics()</Text>}
            {firebase.database.nativeModuleExists && <Text style={styles.module}>database()</Text>}
            {firebase.firestore.nativeModuleExists && <Text style={styles.module}>firestore()</Text>}
            {firebase.functions.nativeModuleExists && <Text style={styles.module}>functions()</Text>}
            {firebase.iid.nativeModuleExists && <Text style={styles.module}>iid()</Text>}
            {firebase.links.nativeModuleExists && <Text style={styles.module}>links()</Text>}
            {firebase.messaging.nativeModuleExists && <Text style={styles.module}>messaging()</Text>}
            {firebase.notifications.nativeModuleExists && <Text style={styles.module}>notifications()</Text>}
            {firebase.perf.nativeModuleExists && <Text style={styles.module}>perf()</Text>}
            {firebase.storage.nativeModuleExists && <Text style={styles.module}>storage()</Text>}
          </View>
        </View>
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    // justifyContent: 'center',
    // alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  logo: {
    height: 120,
    marginBottom: 16,
    marginTop: 64,
    padding: 10,
    width: 135,
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
  modules: {

    margin: 20,
  },
  modulesHeader: {
    fontSize: 16,
    marginBottom: 8,
  },
  module: {
    fontSize: 14,
    marginTop: 4,
    textAlign: 'center',
  }
});

修改QRScanner.js,使掃描發票後自動上傳號碼

/// # ./QRScanner.js
/* eslint-disable prettier/prettier */
import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Text,
  TouchableOpacity,
  Alert,
} from 'react-native';
import QRCodeScanner from 'react-native-qrcode-scanner';
let data = null;
const data_Context = React.createContext(data);

const DB = [
  { "num": "25576066", "txt": "1,000萬元" },
  { "num": "19614436", "txt": "20萬元" },
  { "num": "96182420", "txt": "頭獎20萬元" },
  { "num": "47464012", "txt": "頭獎20萬元" },
  { "num": "62781818", "txt": "頭獎20萬元" },
  { "num": "066", "txt": "頭獎20萬元" },
  { "num": "899", "txt": "頭獎20萬元" },
]
import firebase from 'react-native-firebase';


const iosConfig = {
  clientId: '20749855338-tr7nrc3imleld2r4hod9opgfcpmckptd.apps.googleusercontent.com',
  appId: '1:20749855338:ios:801d1ca9167032feab7813',
  apiKey: 'AIzaSyB15L-Ma87wrfoo3bvkEIItgPB8oB1B_A8',
  databaseURL: 'https://butterbike-9549e.firebaseio.com',
  storageBucket: 'butterbike-9549e.appspot.com',
  messagingSenderId: '20749855338',
  projectId: 'butterbike-9549e',

  // enable persistence by adding the below flag
  persistence: true,
};

const itHelpApp = firebase.initializeApp(iosConfig);

export { data_Context }
export default class Scanner extends Component {
  constructor(props) {
    super(props);
    this.state = {
      userToken: "A",
      camera: false,
      A: false,
      camera_state: true,
      myName: null
    };
  }
  updata(docID,data) {
    // let docID = "HQ255760627"
    const ref = firebase.firestore().collection('receipt').doc(docID);

    itHelpApp.onReady().then((app) => {
      app.firestore()
        .runTransaction(async transaction => {
          const doc = await transaction.get(ref);
          // if it does not exist set the population to one
          if (!doc.exists) {
            transaction.set(ref, { content: data });
            // return the new value so we know what the new population is
            return null;
          }
        })
        .then(newPopulation => {
          console.log(
            `Transaction successfully committed and new population is '${newPopulation}'.`
          );
        })
        .catch(error => {
          console.log('Transaction failed: ', error);
        });
    });
  }


  

  componentDidMount() {
    ///生命週期 component 載入前執行
    // this.updata();

  }
  componentWillReceiveProps(nextProps) {
    this.setState({
      camera: nextProps.camera,
    });
  }


  cutString(str, len, start, suffix) {
    if (!str) return "";
    if (len <= 0) return "";
    if (!suffix) suffix = "";
    var templen = 0;
    for (var i = 0; i < str.length; i++) {
      if (str.charCodeAt(i) > 255) {
        templen += 2;
      } else {
        templen++
      }
      if (templen == len) {
        return str.substring(start, i + 1) + suffix;
      } else if (templen > len) {
        return str.substring(start, i) + suffix;
      }
    }
    return str;
  }
  Checkprize(str) {
    for (i = 0; i < 7; i++) {
      let ANS = str.lastIndexOf(DB[i].num);
      console.warn(DB[i].num)
      if (ANS > 2) {
        // console.warn("WIN~~~")
        let txt = "WIN~~~"
        console.warn(txt)
        return txt
      }
      else if(ANS==0){
        let txt = "~~~WIN~~~"
        console.warn(txt)
        return txt;
      }
      console.warn(ANS,str)
    }
  }

  onSuccess = async (e) => {
    data = e.data;
    let data = this.cutString(e.data, 10, 2);
    let docID = this.cutString(e.data, 10, 0);
    let txt=this.Checkprize(data);
    // Alert.alert(txt,data, e.data);
    Alert.alert(txt,data);
    this.updata(docID,txt);

  }
  render() {
    return (
      <View style={styles.container}>
        <QRCodeScanner
          onRead={this.onSuccess}
          topContent={null}
          reactivate={this.state.camera_state}
          //reactivate={false}
          /////////切換頁面時要關閉/開啟
          reactivateTimeout={1500}
          bottomContent={
            <TouchableOpacity style={styles.buttonTouchable} onPress={() => {
              this.setState({ camera_state: !this.state.camera_state })
              this.testForceFun.bind(this)
            }} >
              <Text style={styles.buttonText}>{this.state.camera_state}</Text>
            </TouchableOpacity>
          }
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white',
  }, centerText: {
    flex: 1,
    fontSize: 18,
    padding: 32,
    color: '#777',
  },
  textBold: {
    fontWeight: '500',
    color: '#000',
  },
  buttonText: {
    fontSize: 21,
    color: 'rgb(0,122,255)',
  },
  buttonTouchable: {
    padding: 16,
  },
});

成功新增發票

https://ithelp.ithome.com.tw/upload/images/20190929/20104220Wjq7Bqj4Tw.png


上一篇
[Day12] 要不要來點潮潮中帶點簡陋的分享功能
下一篇
[Day14] 與 Firebase 結合之自動上傳 DB 記帳(二)
系列文
小孩子才做選擇 ! Flutter & React Native 我全都要32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言